package cn.jja8.config.tool.work.obj.parameterized;

import cn.jja8.config.tool.work.obj.ObjKeepManager;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;

public class TypeKeep {
    final ObjKeepManager objKeepManager;
    final Type type;

    public TypeKeep(ObjKeepManager objKeepManager, Type type) {
        this.objKeepManager = objKeepManager;
        this.type = type;
    }

    /**
     * 将con转换成自己提供的对象
     * */
    <V> V in(Object con){
        try {
            if (type instanceof Class){
                return objKeepManager.getCommonKeepManager().getNoNull((Class<V>)type).in(con);
            }
            if (type instanceof ParameterizedType){
                return objKeepManager.getParameterizedKeepManager()
                        .getNoNull((Class<V>) ((ParameterizedType) type).getRawType())
                        .in(con, Arrays.stream(((ParameterizedType) type)
                                .getActualTypeArguments())
                                .map(ty->new TypeKeep(objKeepManager,ty))
                                .toArray(TypeKeep[]::new)
                        );
            }
            throw new Error("不支持的泛型"+type);
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将自己提供的对象转换成con
     * */
    <V> Object out(V v){
        try {
            if (type instanceof Class){
                return objKeepManager.getCommonKeepManager().getNoNull((Class<V>)type).out(v);
            }
            if (type instanceof ParameterizedType){
                return objKeepManager.getParameterizedKeepManager()
                        .getNoNull((Class<V>) ((ParameterizedType) type).getRawType())
                        .out(v, Arrays.stream(((ParameterizedType) type).getActualTypeArguments())
                                        .map(ty->new TypeKeep(objKeepManager,ty))
                                        .toArray(TypeKeep[]::new)
                        );
            }
            throw new Error("不支持的泛型"+type);
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }
}
